package base.aop.transactional;

import base.dao.BaseDao;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author : GuoFei
 * @date : 2018/12/24 10:10
 */
@Aspect
@Component
@Order(value = 9)
public class GFTransactionalManage {

    @Autowired
    private BaseDao baseDao;

    private final static ThreadLocal<Boolean> NEED_TRANSACTIONAL = new ThreadLocal<>();

    public static boolean needTransactional (){
        return NEED_TRANSACTIONAL.get() == null ? false : NEED_TRANSACTIONAL.get();
    }

    @Around(value = "point()&&@annotation(transactional)")
    public Object around(ProceedingJoinPoint pjp, GFTransactional transactional) {
        Object res = null;
        try {
            if (transactional.need()) {
                NEED_TRANSACTIONAL.set(true);
            }
            res = pjp.proceed();
            baseDao.commitConn();
            NEED_TRANSACTIONAL.remove();
            return res;
        } catch (Throwable throwable) {
            baseDao.rollbackConn();
            throw new RuntimeException();
        }finally {
            baseDao.closeConn();
        }
    }

    @Pointcut(value = "execution(* base..*.*(..))")
    public void point(){}

}
